package org.dprojects.iwebshare.ui.panel;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
import java.util.List;

import org.dprojects.iwebshare.filesystem.FileSystemManager;

import com.googlecode.sardine.DavResource;
import com.googlecode.sardine.Sardine;
import com.googlecode.sardine.SardineFactory;
import com.googlecode.sardine.util.SardineException;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.ProgressIndicator;
import com.vaadin.ui.Tree;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FailedEvent;
import com.vaadin.ui.Upload.SucceededEvent;

public class HomeFolderPanel extends Panel implements Upload.SucceededListener,
Upload.FailedListener, Upload.Receiver {

	/**
	 * 
	 */
	private static final long serialVersionUID = -2499524633966296462L;
	//private static int tableIndex = 1;
	private File file;
	private Tree tree;
	private ProgressIndicator indicator;
	
	private FileSystemManager fileSystemManager;
	
	public HomeFolderPanel(FileSystemManager fileSystemManager) {
		setFileSystemManager(fileSystemManager);
		init();
	}
	
	
	public void init(){
		tree=new Tree("Test Tree");
		
		Button b=new Button("Add item to tree");
		b.addListener(new Button.ClickListener() {
			
			/**
			 * 
			 */
			private static final long serialVersionUID = 3598333681327359033L;

			public void buttonClick(ClickEvent event) {
				//tree.addItem("Ciccio");
				addComponent(tree);
			}
		});
		
		addComponent(b);
		
		//table.addContainerProperty("File name", String.class, null);
		//table.setColumnWidth("Username", 100);
		// table.addContainerProperty("Password", String.class, null);
		// table.addContainerProperty("Dir", String.class, null);
		//table.setWidth(200, Sizeable.UNITS_PIXELS);

		//this.addComponent(table);
		/*
		Session session = HibernateUtil.getSession();
		List<User> l = session.createQuery("from User").list();

		if (l != null) {
			for (User p1 : l) {
				// table.addItem(new Object[] { p1.getUsername(),
				// p1.getPassword(), p1.getDirs().get(0).getPath() },new
				// Integer(i++));
				// table.addItem(getTableItem(new
				// String[]{"username","password","username"},p1),new
				// Integer(i++));
				table.addItem(getTableItem(new String[] { "username" }, p1),
						new Integer(tableIndex++));
			}
		}
		*/
		/*
		Sardine sardine;
		try {
			sardine = SardineFactory.begin("test","welcome");
			List<DavResource> resources = sardine.getResources("http://192.168.2.103/webdav");
			
			
			for (DavResource res : resources)
			{
			     //System.out.println(res); // calls the .toString() method.
				table.addItem(new Object[]{res},tableIndex++);
			}
		} catch (SardineException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		 */
		//webdavClient(table);
		//jackRabbit(table);
		
		//sardine(tree);
		
		
		Upload upload=new Upload("Upload the file here", this);
		// Use a custom button caption instead of plain "Upload". 
		upload.setButtonCaption("Upload Now");
		// Listen for events regarding the success of upload. 
		upload.addListener((Upload.SucceededListener) this); 
		upload.addListener((Upload.FailedListener) this);
		addComponent(upload); 
		addComponent(new Label("Click 'Browse' to "+"select a file and then click 'Upload'."));
		
		
		indicator = new ProgressIndicator(new Float(0.0));
		indicator.addListener(new ValueChangeListener() {
			
			/**
			 * 
			 */
			private static final long serialVersionUID = 1908182307223056517L;

			public void valueChange(ValueChangeEvent event) {
				if(event.getProperty().getValue().equals(new Float(1.0))){
					addComponent(tree);
				}
			}
		});
		addComponent(indicator);
		// Set polling frequency to 0.5 seconds. 
		indicator.setPollingInterval(500);
		
		//new WorkThread().start();

		getFileSystemManager().populate("/Users/dmac/Desktop",tree,indicator);
		
		
	}
	
	
	
	public void sardine(final Tree tree){	
			
			new Thread(){
				
				//private Tree tree;
				
				public void run() {
					try {
						Sardine sardine = SardineFactory.begin("test","welcome");
						List<DavResource> resources = sardine.getResources("http://192.168.2.103/webdav/");
						
						String home="Home directory";
						
						tree.addItem(home);
						
						
						
						for (DavResource res : resources)
						{
						    System.out.println(res); // calls the .toString() method.
						    if(res.isDirectory()){
						    	//FileComponent f=new FileComponent();
						    	//tree.addItem(f);
						    	//tree.setItemIcon(f, f.getIcon());
								//tree.setParent(f, home);
						    }else{
								tree.addItem(res.getAbsoluteUrl());
								tree.setParent(res.getAbsoluteUrl(), home);
						    }
						}
						tree.expandItem(home);
						
					} catch (SardineException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				};
				
			}.start();
			
			
		
	}

	public OutputStream receiveUpload(String filename, String mimeType) {
		FileOutputStream fos = null; // Output stream to write to
		file=new File("/Users/dmac/Desktop/"+filename);
		
		if(file.exists()){
			return null;
		}
		
		
		
		//file=file.getParentFile();
		try {
		
		
			// Open the file for writing.
			fos = new FileOutputStream(file); 
		} catch (final java.io.FileNotFoundException e) {
			// Error while opening the file. Not reported here. 
			e.printStackTrace(); return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return fos; // Return the output stream to write to
	}

	public void uploadFailed(FailedEvent event) {
		System.out.println("Upload Failed");
	}

	public void uploadSucceeded(SucceededEvent event) {
		
		/*
		nioCopy(file, new File("/Users/dmac/Desktop/"+file.getName()));
		
		copy(file, new File("/Users/dmac/Desktop/"+file.getName()));
		*/
		System.out.println("Upload Success");
		
		/*
		Sardine sardine;
		try {
			sardine = SardineFactory.begin("test","welcome");
			InputStream fis = new FileInputStream(file);
			sardine.put("http://192.168.2.103/webdav/"+file.getName(), fis);
			//byte[] data = FileUtils.readFileToByteArray(file);
			//sardine.put("http://yourdavserver.com/adirectory/nameOfFile.jpg", data);
		} catch (SardineException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		*/
		file=null;
	}
	
	/*
	public void webdavClient(Table table){
		try {
			HttpURL url = new HttpURL("http://192.168.2.103");
			url.setUserinfo("test", "welcome");
			url.setPath("/webdav");
			WebdavResource wdr = new WebdavResource(url);
			String[] list = wdr.list();
			
			if(list!=null){
				for (String res : list)
				{
				     //System.out.println(res); // calls the .toString() method.
					table.addItem(new Object[]{res},tableIndex++);
				}
			}
			wdr.close();
			
		} catch (URIException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (HttpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public void jackRabbit(Table table){
		try {
			
			HostConfiguration hostConfig = new HostConfiguration();
	        hostConfig.setHost("http://192.168.2.103/webdav"); 
	        HttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager();
	        HttpConnectionManagerParams params = new HttpConnectionManagerParams();
	        int maxHostConnections = 20;
	        params.setMaxConnectionsPerHost(hostConfig, maxHostConnections);
	        connectionManager.setParams(params);    
	        HttpClient client = new HttpClient(connectionManager);
	        Credentials creds = new UsernamePasswordCredentials("test", "welcome");
	        client.getState().setCredentials(AuthScope.ANY, creds);
	        client.setHostConfiguration(hostConfig);
			
	        String host = "http://192.168.2.103";
	        String resourcePath = "/webdav";
	        DavMethod pFind =  new PropFindMethod(host + resourcePath, DavConstants.PROPFIND_ALL_PROP, DavConstants.DEPTH_1);
	        client.executeMethod(pFind);

	        MultiStatus multiStatus = pFind.getResponseBodyAsMultiStatus();
	        MultiStatusResponse[] responses = multiStatus.getResponses();
	        MultiStatusResponse currResponse;
	        //ArrayList files = new ArrayList();
	        System.out.println("Folders and files in " + resourcePath + ":");
	        for (int i=0; i<responses.length; i++) {
	            currResponse = responses[i];
	            if (!(currResponse.getHref().equals(resourcePath) || currResponse.getHref().equals(resourcePath + "/"))) {
	                System.out.println(currResponse.getHref());
	            }
	        }  
			
		} catch (URIException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (HttpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DavException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	*/
	
	
	public void setFileSystemManager(FileSystemManager fileSystemManager) {
		this.fileSystemManager = fileSystemManager;
	}

	public FileSystemManager getFileSystemManager() {
		return fileSystemManager;
	}

	/*
	class WorkThread extends Thread {
	
		public void run (){ 
			double current=0.0;
			
			while (true) {
				try{
					sleep(250);
				}catch (InterruptedException e) {
					// TODO: handle exception
				}
				current += 0.01;
				if (current>1.0){
					indicator.setValue(new Float(1.0)); 	
				}else{
					indicator.setValue(new Float(current));
				}
				
				if (current > 1.2) {
					//indicator.setValue(new Float(0.0)); 
					break;
				}
			}
			
		}
	}
	*/
	
	public void nioCopy(File s,File t){
		int maxCount = (64 * 1024 * 1024) - (32 * 1024); //Windows hack 64M - 32k
        
		try {
			long startTime = System.currentTimeMillis();
			FileChannel in = (new FileInputStream(s)).getChannel();
			FileChannel out = (new FileOutputStream(t)).getChannel();
			
			long size = in.size();
	        long position = 0;
	        while (position < size) {
	           position += 
	             in.transferTo(position, maxCount, out);
	        }
			//in.transferTo(0, s.length(), out);
			in.close();
			out.close();
			long endTime = System.currentTimeMillis();
			System.out.println("Nio copy "+ (endTime - startTime));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	      
	}
	
	 public void copy(File s, File t){

		try {
			long startTime = System.currentTimeMillis();
			InputStream in = new FileInputStream(s);
			  FileOutputStream out = new FileOutputStream(t);
		      
		      final int BUFF_SIZE = 5 * 1024 * 1024; // 5MB
		      final byte[] buffer = new byte[BUFF_SIZE];

		      while (true) {
		        int count = in.read(buffer);
		        if (count == -1)
		          break;
		        out.write(buffer, 0, count);
		      }
		      out.close();
		      in.close();
		      long endTime = System.currentTimeMillis();
		      System.out.println("Standard copy "+ (endTime - startTime));
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    }
	
	
	
}
